package com.mt.mall.service.good.impl;

import com.mt.common.core.web.JsonResult;
import com.mt.mall.dao.good.ShoppingCartDao;

import com.mt.common.core.exception.BusinessException;
import com.mt.common.core.web.base.PageDTO;
import com.mt.common.core.web.base.PageResultDTO;
import com.mt.common.core.web.base.BaseEntity;
import com.mt.common.core.web.BaseService;
import com.mt.mall.dto.good.ShippingCartDto;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.mt.mall.entity.good.ShoppingCart;
import com.mt.mall.service.good.ShoppingCartService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
public class ShoppingCartServiceBean extends BaseService implements ShoppingCartService {

    private static Logger logger = LogManager.getLogger();

	@Autowired
	private ShoppingCartDao shoppingCartDao;

	@Resource
	private RedisTemplate<String, List<ShoppingCart>> redisTemplate;

	@Autowired
	StringRedisTemplate stringRedisTemplate;

	/**
	 * 根据分页参数查询购物车集合
	 *
	 * @param pageDTO 分页条件
	 */
	@Override
	public PageResultDTO findShoppingCarts(PageDTO pageDTO){
        pageDTO.setStartIndex((pageDTO.getCurrentPage()-1)*pageDTO.getPageSize());
		//TODO:请在此校验参数的合法性
		this.validateFindShoppingCarts(pageDTO);
		List<ShoppingCart> shoppingCartDTOS = this.shoppingCartDao.findShoppingCarts(pageDTO);
		Long totalCount = this.shoppingCartDao.findShoppingCartTotalCount(pageDTO);

		PageResultDTO pageResultDTO = new PageResultDTO();
		pageResultDTO.setTotalCount(totalCount);
		pageResultDTO.setDatas(shoppingCartDTOS);

		return pageResultDTO;
	}

	@Override
	public PageResultDTO findUserShoppingCarts(PageDTO pageDTO) {
		pageDTO.setStartIndex((pageDTO.getCurrentPage()-1)*pageDTO.getPageSize());
		//TODO:请在此校验参数的合法性
		this.validateFindShoppingCarts(pageDTO);
		Map<String, Object> map =new HashMap<>();
		map.put("userId",this.getLoginUserId());
		map.put("status","0");
		pageDTO.setFilters(map);
		//pageDTO.setFilterTypes((Map<String, String>) new HashMap<>().put("userId","单值"));

		List<ShippingCartDto> shoppingCartDTOS = this.shoppingCartDao.findShippingCartForDis(pageDTO);
		//Long totalCount = this.shoppingCartDao.findShoppingCartTotalCount(pageDTO);

		PageResultDTO pageResultDTO = new PageResultDTO();
		//pageResultDTO.setTotalCount(totalCount);
		pageResultDTO.setDatas(shoppingCartDTOS);

		return pageResultDTO;
	}

	@Override
	public void delShoppingCart(List<Long> shoppingCartIds) {
		this.shoppingCartDao.delShoppingCart(shoppingCartIds);
	}

	/**
	 * 查询全部购物车集合
	 *
	 */
	@Override
	public List<ShoppingCart> findAllShoppingCarts(){
		return this.shoppingCartDao.findAllShoppingCarts();
	}

	/**
	 * 查询所有购物车集合(只提取ID 和 Name)
	 *
	 */
	@Override
	public List<ShoppingCart> findAllShoppingCartsWithIdName(){
		//TODO:请在此校验参数的合法性
		this.validateFindAllShoppingCartsWithIdName();
		return this.shoppingCartDao.findAllShoppingCartsWithIdName();
	}

	/**
	 * 根据名称查询购物车集合(只提取ID 和 Name)
	 *
	 * @param shoppingCartName 名称
	 */
	@Override
	public List<ShoppingCart> findShoppingCartsWithIdNameByName(String shoppingCartName){
		//TODO:请在此校验参数的合法性
		this.validateFindShoppingCartsWithIdNameByName(shoppingCartName);
		//TODO:缓存取对应参数
		Set<String> keys = stringRedisTemplate.keys("searchData:ShoppingCart_where_shoppingCartName_" + shoppingCartName);
		List<ShoppingCart> shoppingCarts = new ArrayList<>();
		if (keys.isEmpty()) {
		shoppingCarts = this.shoppingCartDao.findShoppingCartsWithIdNameByName(shoppingCartName);
		redisTemplate.opsForValue().set("searchData:ShoppingCart_where_shoppingCartName_" + shoppingCartName, shoppingCarts, 30, TimeUnit.DAYS);
		} else {
		shoppingCarts = redisTemplate.opsForValue().get("searchData:ShoppingCart_where_shoppingCartName_" + shoppingCartName);
		}
		return shoppingCarts;
	}

	/**
	 * 根据ID查询指定的购物车(只提取ID 和 Name)
	 *
	 * @param shoppingCartId Id
	 */
	@Override
	public ShoppingCart findShoppingCartsWithIdNameById(Long shoppingCartId){
		//TODO:请在此校验参数的合法性
		this.validateFindShoppingCartsWithIdNameById(shoppingCartId);
		return this.shoppingCartDao.findShoppingCartsWithIdNameById(shoppingCartId);
	}

	/**
	 * 根据ID查询指定的购物车
	 *
	 * @param shoppingCartId Id
	 */
	@Override
	public ShoppingCart findShoppingCart(Long shoppingCartId){
		//TODO:请在此校验参数的合法性
		this.validateFindShoppingCart(shoppingCartId);
		return this.shoppingCartDao.findShoppingCart(shoppingCartId);
	}

	/**
	 * 根据ID查询指定的购物车(包含外键)
	 *
	 * @param shoppingCartId Id
	 */
	@Override
	public ShoppingCart findShoppingCartWithForeignName(Long shoppingCartId){
		//TODO:请在此校验参数的合法性
		this.validateFindShoppingCartWithForeignName(shoppingCartId);
		return this.shoppingCartDao.findShoppingCartWithForeignName(shoppingCartId);
	}

	/**
	 * 新增购物车
	 *
	 * @param shoppingCart 实体对象
	 */
	@Override
	public ShoppingCart saveShoppingCart(ShoppingCart shoppingCart){
		//TODO:请在此校验参数的合法性
		this.validateSaveShoppingCart(shoppingCart);
		//TODO:填充公共参数
		this.setSavePulicColumns(shoppingCart);
		Long rows = this.shoppingCartDao.saveShoppingCart(shoppingCart);
		if(rows != 1)
		{
			String error = "新增保存购物车出错，数据库应该返回1,但返回了 "+rows;
			throw new BusinessException(error);
		}
		return shoppingCart;
	}

	/**
	 * 更新购物车
	 *
	 * @param shoppingCart 实体对象
	 */
	@Override
	public ShoppingCart updateShoppingCart(ShoppingCart shoppingCart){
		//TODO:请在此校验参数的合法性
		this.validateUpdateShoppingCart(shoppingCart);
		Long rows = this.shoppingCartDao.updateShoppingCart(shoppingCart);
		if(rows != 1)
		{
			String error = "修改保存购物车出错，数据库应该返回1,但返回了 "+rows+",数据可能被删除";
			throw new BusinessException(error);
		}
		return shoppingCart;
	}

	@Override
	public ShoppingCart addShoppingCart(ShoppingCart shoppingCart) {
		shoppingCart.setUserId(this.getLoginUserId());
		shoppingCart.setStatus("0");
		//查询数据库中是否有当前商品对应规格的物品
		Long id=this.shoppingCartDao.findShoppingCartIdByCommodity(shoppingCart.getCommodityId(),shoppingCart.getSpecification(),shoppingCart.getUserId());
		if(id!=null){
			this.shoppingCartDao.updateCount(id,shoppingCart.getCount());
			return shoppingCart;
		}
		return this.saveShoppingCart(shoppingCart);
	}


	/**
	 * 根据ID删除购物车
	 *
	 * @param shoppingCartId ID
	 */
	@Override
	public void deleteShoppingCart(Long shoppingCartId){
		//TODO:请在此校验参数的合法性
		this.validateDeleteShoppingCart(shoppingCartId);

		Map<Class<? extends BaseEntity>,EntityUsage> entityUsageMap = this.checkForeignEntity(ShoppingCart.class, shoppingCartId);
		if(entityUsageMap != null && entityUsageMap.size() >0){
			StringBuilder errors = new StringBuilder();
			errors.append("计划删除的数据正在被以下数引用\n");
			for(EntityUsage entityUsage : entityUsageMap.values()){
				errors.append("\t").append(entityUsage.getEntityLabel()).append("\n");
				for(Map.Entry<Long,String> entry : entityUsage.getUsageIdNames().entrySet() ){
					errors.append("\t\t").append(entry.getKey()).append("\t").append(entry.getValue()).append("\n");
				}
			}
			errors.append("，不能删除，请检查处理后再删除");
			throw  new BusinessException(errors.toString());
		}

		Long rows = this.shoppingCartDao.deleteShoppingCart(shoppingCartId);
		if(rows != 1){
			String error = "删除购物车出错，数据可能已经被删除";
			throw new BusinessException(error);
		}
	}

	@Override
	public JsonResult updateCount(Long shoppingCartId, Integer count) {
		this.shoppingCartDao.updateCount(shoppingCartId,count);
		return JsonResult.ok("更新成功");
	}

	@Override
	public JsonResult settlement(Long shoppingCartId) {
		this.shoppingCartDao.settlement(shoppingCartId);
		return JsonResult.ok("结算修改成功");
	}
	//TODO:---------------验证-------------------

	private void validateFindShoppingCarts(PageDTO pageDTO) {
	//TODO:请使用下面方法添加数据过滤条件
	//		pageDTO.addFilter("creatorId",this.getLoginUserId());
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateShoppingCart()写法
	}

	private void validateFindShoppingCartsWithIdNameByName(String shoppingCartName) {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateShoppingCart()写法
	}


	private void validateFindAllShoppingCartsWithIdName() {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateShoppingCart()写法
	}

	private void validateFindShoppingCartsWithIdNameById(Long shoppingCartId) {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateShoppingCart()写法
	}

	private void validateFindShoppingCart(Long shoppingCartId) {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateShoppingCart()写法
	}

	private void validateFindShoppingCartWithForeignName(Long shoppingCartId) {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateShoppingCart()写法
	}

	private void validateSaveShoppingCart(ShoppingCart shoppingCart) {
	//不为空判断
	if (shoppingCart.getEid() != null || shoppingCart.getCreatorId() != null || shoppingCart.getCreateDatetime() != null) {
	throw new BusinessException("非法请求");
	}
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateShoppingCart()写法
	}

	private void validateUpdateShoppingCart(ShoppingCart shoppingCart) {
	//不为空判断
	if (shoppingCart.getEid() == null) {
	throw new BusinessException("唯一标识不能为空");
	}
	//是否存在判断
	if (this.shoppingCartDao.findShoppingCartTotalCount(PageDTO.create(ShoppingCart.FIELD_ID, shoppingCart.getEid())) == 0) {
	throw new BusinessException("修改的购物车 " + shoppingCart.getName() + " 不存在，修改失败，请重试或联系管理员");
	}
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateShoppingCart()写法
	}

	private void validateDeleteShoppingCart(Long shoppingCartId) {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateShoppingCart()写法
	}

	@Override
	public boolean canDownloadAttachment(String formName, Long id) {
	return true;
	}
}
